/*
 * @Author: yzr
 * @Date: 2023-09-18 14:22:35
 * @LastEditors: yzr
 * @LastEditTime: 2023-10-12 16:31:30
 * @Description:
 * @FilePath: /utilization/src/pages/utiAnalysis/static/components/rateChat/index.tsx
 */
import { useEffect, useRef, useState } from 'react';
import { Checkbox, Button, Select, Space, message } from 'antd';
import Card from '@/components/Card';
import Chart from '@/components/Chart';
import BeforefixSelect from '@/components/BeforefixSelect';
import MyRangePicker from '@/components/RangePicker';
import { graphic } from '@/utils/echartConfig';
import type { ChartRef } from '@/components/Chart';
import type { EChartsOption } from 'echarts';

import { useDebounceFn, useRequest, useToggle } from 'ahooks';
import { getDeviceList, getDepList, getDeviceModels } from '@/api/device';
import { getUtilRateTrend, exportUtilRateTrebd } from '@/api/analysis';

import { downloadExcel, deCodeArrayBuffer } from '@/utils';

import style from './index.module.scss';

const { Option } = Select;

const contrastOptions = [
  {
    label: '按部门对比',
    value: 'dept',
  },
  {
    label: '按设备对比',
    value: 'device',
  },
  {
    label: '按型号对比',
    value: 'model',
  },
];

interface Iprops {
  deviceTypeOptions: any;
}

const RateChat: React.FC<Iprops> = ({ deviceTypeOptions }) => {
  const rangeRef: any = useRef(null);
  const chartRef = useRef<ChartRef>(null);
  // 计划利用率
  const [planRate, setPlanRate] = useState<number>(0);
  // 设备类型
  const [deviceType, setDeviceType] = useState<number>();
  // 维度
  const [contrast, setContrast] = useState<string>();
  // 维度值
  const [contrastValue, setContrastValue] = useState<any[]>([]);
  // 维度下拉
  const [valueOptions, setValueOptions] =
    useState<{ label: any; value: any }[]>();
  const [openContract, { toggle: open }] = useToggle(false);

  // 获取部门列表
  const { run: depRun } = useRequest(
    () => getDepList({ deviceType: String(deviceType) }),
    {
      manual: true,
      onSuccess: res => {
        const options = res.data.map(r => ({
          label: r,
          value: r,
        }));
        setValueOptions(options);
      },
    }
  );
  // 获取设备列表
  const { run: deviceRun } = useRequest(
    () =>
      getDeviceList({
        page: 1,
        pageSize: 9999,
        deviceTypes: [String(deviceType)],
      }),
    {
      manual: true,
      onSuccess: res => {
        const options = res.data.records?.map(r => ({
          label: r.deviceCode,
          value: r.deviceCode,
        }));
        setValueOptions(options);
      },
    }
  );
  // 获取型号列表
  const { run: deviceModelRun } = useRequest(
    () => getDeviceModels({ deviceType: String(deviceType) }),
    {
      manual: true,
      onSuccess: res => {
        const options = res.data.map((r: any) => ({
          label: r?.model,
          value: r?.model,
        }));
        setValueOptions(options);
      },
    }
  );

  const onDeviceTypeChange = (val: number) => {
    setDeviceType(val);
  };
  const onContrastChange = (val: string) => {
    switch (val) {
      case 'dept':
        depRun();
        break;
      case 'device':
        deviceRun();
        break;
      case 'model':
        deviceModelRun();
        break;
      default:
        break;
    }
    setContrast(val);
    // 清空维度值
    setContrastValue([]);
  };
  const onContrastValueChange = (val: any) => {
    setContrastValue(val);
  };

  useEffect(() => {
    onContrastChange(contrast || 'device');
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [deviceType]);

  // chart相关参数
  const [legendData, setLegendData] = useState<string[]>([]);
  const [xAxisData, setXAxisData] = useState<string[]>([]);
  const [seriesData, setSeriesData] = useState<any[]>();
  const [showLine, { toggle }] = useToggle(false);
  let option: EChartsOption = {
    tooltip: {
      trigger: 'axis',
      confine: true,
      axisPointer: {
        type: 'line',
        lineStyle: {
          type: 'solid',
          opacity: 0.08,
          color: '#7590FF',
          width: 76,
        },
      },
      formatter: (params: any) => {
        // 两列
        // let name = `<div>${params[0].axisValue.replace(/-/g, '/')}</div>`;
        // for (let i = 0; i < params.length; i++) {
        //   name += `<div style="width: 40%;float:left;">${params[i].marker}${
        //     params[i].seriesName
        //   }<span style="color: #191B27; font-weight: bold;margin-left: 10px">${`${params[
        //     i
        //   ].value.toFixed(0)}%`}</span></div>`;
        // }
        // return `<div style="width: 300px">${name}</div>`;

        let name = params[0].axisValue.replace(/-/g, '/');
        for (let i = 0; i < params.length; i++) {
          name += `<br />${params[i].marker}${
            params[i].seriesName
          }<span style="color: #191B27; font-weight: bold;margin-left: 10px">${`${params[
            i
          ].value.toFixed(0)}%`}</span>`;
        }
        return name;
      },
    },
    legend: {
      type: 'scroll',
      icon: 'pin',
      top: 10,
      width: 400,
      right: 5,
      data: legendData,
    },
    color: [
      '#57D7E4',
      '#5985FF',
      '#8D64FF',
      '#AA3BF9',
      '#393EFF',
      '#FFAA4E',
      '#F16565',
      '#ED4D9E',
      '#4BDE70',
      '#EAEA08',
    ],
    grid: {
      borderWidth: 0,
      left: 55,
      right: 50,
      top: 65,
      bottom: 60,
    },
    xAxis: [
      {
        type: 'category',
        boundaryGap: false,
        data: xAxisData,
      },
      {
        show: showLine,
        type: 'category',
        boundaryGap: false,
        offset: -(275 - 275 * planRate),
        axisLine: {
          onZero: false,
          lineStyle: {
            type: 'dashed',
            color: '#4E6FF5',
          },
        },
      },
    ],
    yAxis: {
      // name: '%',
      type: 'value',
      splitNumber: 4,
      max: 100,
      maxInterval: 25,
      axisLabel: {
        formatter: '{value} %',
      },
    },
    dataZoom: [
      {
        type: 'inside',
        start: 0,
        end: 100,
      },
      {
        type: 'slider',
        start: 0,
        end: 100,
        height: 0,
        xAxisIndex: [0],
        bottom: 10,
        handleIcon:
          'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
        handleSize: '100%',
        textStyle: {
          color: '#fff',
        },
        borderColor: '#f2f3f7',
        fillerColor: '#e9e8ed',
        moveHandleStyle: {
          color: 'rgba(144, 147, 153, 0.3)',
        },
      },
    ],
    series: seriesData,
  };
  const { data: trendData, run: searchTrend } = useRequest(
    () =>
      getUtilRateTrend({
        deviceType: String(deviceType),
        comparisonDimension: contrast,
        timeDimensionType:
          rangeRef.current.picker === 'date' ? 'day' : rangeRef.current.picker,
        startTime: rangeRef.current.date[0],
        endTime: rangeRef.current.date[1],
        comparisonItems: contrastValue,
        isComparison: openContract,
      }),
    {
      manual: true,
      onSuccess: res => {
        // console.log(res);
        setPlanRate(res.data.plannedUtilization);
        const legList: any[] = [];
        let xAxisList: any[] = [];
        const seriesList: any[] = [];
        res.data.comparisonItemRates.forEach(com => {
          xAxisList = [];
          const series: any = {
            name: com.comparisonItem,
            type: 'line',
            data: [],
          };
          legList.push(com.comparisonItem);
          com.utilizationRates.forEach(util => {
            xAxisList.push(util.statisticsTime);
            series.data.push(util.utilizationRate * 100);
          });
          seriesList.push(series);
        });
        setLegendData(legList);
        setXAxisData(xAxisList);
        setSeriesData(seriesList);
      },
    }
  );

  useEffect(() => {
    const chartInstance = chartRef.current?.getChartInstance();
    chartInstance?.setOption(option);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [seriesData]);

  const { run: onSearch } = useDebounceFn(
    () => {
      if (!deviceType) return message.error('请选择设备类型');
      if (rangeRef.current.date.length === 0)
        return message.error('请选择查询时间');
      if (openContract && !contrast)
        return message.error('请选择对比维度和对比值');
      if (openContract && !contrastValue.length)
        return message.error('请选择对比维度和对比值');
      searchTrend();
    },
    { wait: 300 }
  );
  // 导出
  const { loading: exportLoading, run: exportTrend } = useRequest(
    () =>
      exportUtilRateTrebd({
        deviceType: String(deviceType),
        comparisonDimension: contrast,
        timeDimensionType:
          rangeRef.current.picker === 'date' ? 'day' : rangeRef.current.picker,
        startTime: rangeRef.current.date[0],
        endTime: rangeRef.current.date[1],
        comparisonItems: contrastValue,
        isComparison: openContract,
      }),
    {
      manual: true,
      onSuccess: (res: any) => {
        if (res.headers['content-disposition']) {
          downloadExcel(
            res.data,
            decodeURI(
              res.headers['content-disposition'].split('=')[1].split(';')[0]
            )
          );
        } else {
          const resposeData = deCodeArrayBuffer(res.data);
          if (resposeData && resposeData.errorCode) {
            message.error(resposeData.errorMsg);
          }
        }
      },
    }
  );

  return (
    <Card title="利用率趋势">
      <div className={style.searchArea}>
        <div className="flex-s-b">
          <Space size="middle">
            <BeforefixSelect
              key="deviceType"
              style={{ minWidth: '160px' }}
              beforefix="设备类型"
              placeholder="请选择设备类型"
              onChange={onDeviceTypeChange}
              options={deviceTypeOptions}
            />
            <MyRangePicker ref={rangeRef} />
            <Checkbox
              style={{ margin: '0 4px 0 8px', lineHeight: '32px' }}
              onChange={open}>
              开启对比
            </Checkbox>
          </Space>

          <Space size="middle">
            <Button type="primary" onClick={onSearch}>
              查询
            </Button>
            <Button
              loading={exportLoading}
              type="primary"
              ghost
              onClick={() => {
                if (!deviceType) return message.error('请选择设备类型');
                exportTrend();
              }}>
              导出
            </Button>
          </Space>
        </div>

        {openContract && (
          <Space
            size="middle"
            style={{
              display: 'flex',
              flexWrap: 'wrap',
              width: '100%',
              marginTop: '8px',
            }}>
            <BeforefixSelect
              key="contrast"
              style={{ minWidth: '160px' }}
              beforefix="对比维度"
              placeholder="请选择对比维度"
              onChange={onContrastChange}
              options={contrastOptions}
            />
            <Select
              style={{ minWidth: '262px' }}
              mode="multiple"
              allowClear
              maxTagCount={2}
              placeholder="请选择"
              optionLabelProp="label"
              value={contrastValue}
              onChange={onContrastValueChange}>
              {valueOptions?.map(item => {
                return (
                  <Option
                    value={item.value}
                    label={item.label}
                    key={item.value}
                    className="checkbox-select"
                    style={{ padding: '0 8px 0 0' }}>
                    <div
                      style={{
                        position: 'absolute',
                        width: '100%',
                        height: '100%',
                        padding: '5px 12px',
                        boxSizing: 'border-box',
                      }}></div>
                    <Checkbox
                      style={{
                        width: '100%',
                        height: '100%',
                        padding: '5px 12px',
                        boxSizing: 'border-box',
                      }}
                      checked={contrastValue.includes(item.value as string)}>
                      {item.label}
                    </Checkbox>
                  </Option>
                );
              })}
            </Select>
          </Space>
        )}
      </div>

      <div style={{ height: '400px', position: 'relative' }}>
        <div className={style.checkbox}>
          <Checkbox onChange={toggle}>显示计划利用率</Checkbox>
        </div>
        <Chart
          option={trendData?.data ? option : { graphic }}
          ref={chartRef}
          notMerge={true}
          opts={{ useDirtyRect: true }}
          chartStyle={{ height: '100%' }}
        />
      </div>
    </Card>
  );
};

export default RateChat;
